%     FASTENER DOCTOR - программа для лечения и конвертации крепежа
%     Copyright (C) 2018  Михаил Козлов
%     Сайт проекта: <http://www.fastenerdoctor.ru/>
%     Адрес электронной почты для связи с разработчиком:
%     <doctor.fastener@gmail.com>
% 
%     Эта программа является свободным программным обеспечением: Вы можете
%     распространять ее и/или изменять, соблюдая условия Универсальной общественной
%     лицензии GNU, опубликованной Фондом свободного программного обеспечения,
%     либо редакции 3, либо (на Ваше усмотрение) любой редакции, выпущенной позже.
% 
%     Эта программа распространяется в надежде на то, что она окажется полезной,
%     но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, включая даже подразумеваемую гарантию ТОВАРНОЙ ПРИГОДНОСТИ,
%     либо ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Ознакомьтесь с Универсальной общественной
%     лицензией GNU для получения более подробной информации.
% 
%     Вы должны были получить копию Универсальной общественной лицензии GNU
%     вместе с этой программой. Если Вы ее не получили, то перейдите по адресу:
%     <http://www.gnu.org/licenses/>.
% 
%     This program is free software: you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation, either version 3 of the License, or
%     (at your option) any later version.
% 
%     This program is distributed in the hope that it will be useful,
%     but WITHOUT ANY WARRANTY; without even the implied warranty of
%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
%     GNU General Public License for more details.
% 
%     You should have received a copy of the GNU General Public License
%     along with this program.  If not, see <https://www.gnu.org/licenses/>.

function Task_Repair_BarFast(BarFast_Repair_Offsets, BarFast_Repair_2D_Holes, BarFast_Repair_3D_Holes)

global ErrCode;

global DB_FASTENERS;

if (size(DB_FASTENERS,1) == 0)
    fprintf (1, 'Пустая база данных крепежа!\n');
    ErrCode = -1;
    return;
end

% Инициализация счетчиков

Moved_2D_Hole_Center_Node_Counter = 0;
Moved_3D_Hole_Center_Node_Counter = 0;
Max_2D_Hole_Displacement = 0;
Max_3D_Hole_Displacement = 0;

Repaired_Offsets_Counter = 0;
Removed_Offsets_Counter = 0;
Repaired_Offset_MPC_Counter = 0;
Created_Offset_MPC_Counter = 0;

Fastener_Repair_Flags = zeros(size(DB_FASTENERS,1),1);

fprintf (1, '    Ход выполнения:\n');

% --- Перемещение центрального узла MPC или bar-паука вдоль оси болта в центр 2D отверстия ---

switch BarFast_Repair_2D_Holes
    
    case 'TRUE'
        
        fprintf (1, '        Починка центральных узлов 2D отверстий...   ');
        
        % Цикл по всем болтам
        for i=1:size(DB_FASTENERS,1)
            
            % Если болт балочный
            if (strcmp(DB_FASTENERS{i}.topology, 'bar_fastener'))
            
                % Исправление центральных узлов 2D отверстий
                [temp_counter_1, temp_counter_2] = Repair_BarFast_2D_Holes(i);
                
                if (ErrCode < 0)
                    return;
                end
                
                % Обновление счетчиков
                Moved_2D_Hole_Center_Node_Counter = Moved_2D_Hole_Center_Node_Counter + temp_counter_1;
                
                if (temp_counter_2 > Max_2D_Hole_Displacement)
                    Max_2D_Hole_Displacement = temp_counter_2;
                end
				
                if (temp_counter_1 > 0)
                    Fastener_Repair_Flags(i) = 1;
                end
            
            end
            
        end
        
        fprintf (1, 'OK!\n');
        
    case 'FALSE'
        % Ничего не делаем
        
    otherwise
        fprintf (1, 'Недопустимое значение параметра BarFast_Repair_2D_Holes !\n');
        ErrCode = -1;
        return;
        
end

% --- Перемещение центрального узла MPC или bar-паука вдоль оси болта в центр 3D отверстия ---

switch BarFast_Repair_3D_Holes
    
    case 'TRUE'
        
        fprintf (1, '        Починка центральных узлов 3D отверстий...   ');
        
        % Цикл по всем болтам
        for i=1:size(DB_FASTENERS,1)
            
            % Если болт балочный
            if (strcmp(DB_FASTENERS{i}.topology, 'bar_fastener'))
            
                % Исправление центральных узлов 3D отверстий
                [temp_counter_1, temp_counter_2] = Repair_BarFast_3D_Holes(i);
                
                if (ErrCode < 0)
                    return;
                end
                
                % Обновление счетчиков
                Moved_3D_Hole_Center_Node_Counter = Moved_3D_Hole_Center_Node_Counter + temp_counter_1;
                
                if (temp_counter_2 > Max_3D_Hole_Displacement)
                    Max_3D_Hole_Displacement = temp_counter_2;
                end
				
                if (temp_counter_1 > 0)
                    Fastener_Repair_Flags(i) = 1;
                end
            
            end
            
        end
        
        fprintf (1, 'OK!\n');
        
    case 'FALSE'
        % Ничего не делаем
        
    otherwise
        fprintf (1, 'Недопустимое значение параметра BarFast_Repair_3D_Holes !\n');
        ErrCode = -1;
        return;
        
end

% --- Починка/удаление офсетов точек смятия ---

switch BarFast_Repair_Offsets
    
    case 'TRUE'
        
        fprintf (1, '        Починка офсетов точек смятия...             ');
        
        % Цикл по всем болтам
        for i=1:size(DB_FASTENERS,1)
            
            % Если болт балочный
            if (strcmp(DB_FASTENERS{i}.topology, 'bar_fastener'))
                
                % Исправление офсетов точек смятия
                [temp_counter_1, temp_counter_2, temp_counter_3] = Repair_BarFast_Offsets(i);
                
                if (ErrCode < 0)
                    return;
                end
                
                % Обновление счетчиков
                Repaired_Offset_MPC_Counter = Repaired_Offset_MPC_Counter + temp_counter_1;
                Created_Offset_MPC_Counter = Created_Offset_MPC_Counter + temp_counter_2;
                Repaired_Offsets_Counter = Repaired_Offsets_Counter + temp_counter_3;
				
                if ((temp_counter_1 > 0) || (temp_counter_2 > 0) || (temp_counter_3 > 0))
                    Fastener_Repair_Flags(i) = 1;
                end
                
            end
            
        end
        
        fprintf (1, 'OK!\n');
        
    case 'REMOVE'
        
        fprintf (1, '        Удаление офсетов точек смятия...            ');
        
        % Цикл по всем болтам
        for i=1:size(DB_FASTENERS,1)
            
            % Если болт балочный
            if (strcmp(DB_FASTENERS{i}.topology, 'bar_fastener'))
                
                % Удаление офсетов точек смятия
                temp_counter_1 = Remove_BarFast_Offsets(i);
                
                if (ErrCode < 0)
                    return;
                end
                
                % Обновление счетчиков
                Removed_Offsets_Counter = Removed_Offsets_Counter + temp_counter_1;
				
                if (temp_counter_1 > 0)
                    Fastener_Repair_Flags(i) = 1;
                end
                
            end
            
        end
        
        fprintf (1, 'OK!\n');
        
    case 'FALSE'
        % Ничего не делаем
        
    otherwise
        fprintf (1, 'Недопустимое значение параметра BarFast_Repair_Offsets !\n');
        ErrCode = -1;
        return;
        
end

% --- Вывод статистики ---

fprintf (1, '\n    Статистика:\n');

% Общий счетчик исправленных болтов
fprintf (1, '                 Всего исправлено балочных болтов: %i\n', sum(Fastener_Repair_Flags));

% Счетчики починки центральных узлов 2D отверстий
if (strcmp(BarFast_Repair_2D_Holes, 'TRUE'))
    fprintf (1, '        Исправлено центральных узлов 2D отверстий: %i', Moved_2D_Hole_Center_Node_Counter);
    if (Moved_2D_Hole_Center_Node_Counter > 0)
        fprintf (1, ', максимальная коррекция: %f\n', Max_2D_Hole_Displacement);
    else
        fprintf (1, '\n');
    end
end

% Счетчики починки центральных узлов 3D отверстий
if (strcmp(BarFast_Repair_3D_Holes, 'TRUE'))
    fprintf (1, '        Исправлено центральных узлов 3D отверстий: %i', Moved_3D_Hole_Center_Node_Counter);
    if (Moved_3D_Hole_Center_Node_Counter > 0)
        fprintf (1, ', максимальная коррекция: %f\n', Max_3D_Hole_Displacement);
    else
        fprintf (1, '\n');
    end
end

% Счетчики починки офсетов точек смятия
if (strcmp(BarFast_Repair_Offsets, 'TRUE'))
    if (Repaired_Offset_MPC_Counter > 0)
        fprintf (1, '                       Исправлено MPC для офсетов: %i\n', Repaired_Offset_MPC_Counter);
    end
    fprintf (1, '                          Создано MPC для офсетов: %i\n', Created_Offset_MPC_Counter);
    fprintf (1, '                  Исправлено офсетов точек смятия: %i\n', Repaired_Offsets_Counter);
end

if (strcmp(BarFast_Repair_Offsets, 'REMOVE'))
    fprintf (1, '                     Удалено офсетов точек смятия: %i\n', Removed_Offsets_Counter);
end
